//
//  LGWeekdayCalendar.m
//  LGSanofiPatient
//
//  Created by 1234 on 2022/8/29.
//

#import "LGWeekdayCalendar.h"
//#import "FSCalendarCalculator.h"
//#import "FSCalendarDelegationProxy.h"
//#import "FSCalendarDelegationFactory.h"
#import "FSCalendarExtensions.h"

#define viewWidth      self.bounds.size.width
#define viewHeight     self.bounds.size.height

NS_ASSUME_NONNULL_BEGIN
static inline void FSCalendarAssertDateInBounds(NSDate *date, NSCalendar *calendar, NSDate *minimumDate, NSDate *maximumDate) {
    BOOL valid = YES;
    NSInteger minOffset = [calendar components:NSCalendarUnitDay fromDate:minimumDate toDate:date options:0].day;
    valid &= minOffset >= 0;
    if (valid) {
        NSInteger maxOffset = [calendar components:NSCalendarUnitDay fromDate:maximumDate toDate:date options:0].day;
        valid &= maxOffset <= 0;
    }
    if (!valid) {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        formatter.dateFormat = @"yyyy/MM/dd";
        [NSException raise:@"FSCalendar date out of bounds exception" format:@"Target date %@ beyond bounds [%@ - %@]", [formatter stringFromDate:date], [formatter stringFromDate:minimumDate], [formatter stringFromDate:maximumDate]];
    }
}
NS_ASSUME_NONNULL_END

@interface LGWeekdayCalendar()<UICollectionViewDelegate,UICollectionViewDataSource>
/**   */
@property (nonatomic , strong)UICollectionView *collectionView;
@property (nonatomic , strong)NSDateFormatter *formatter;
@property (nonatomic , strong)NSCalendar *calendar;
/**   */
@property (nonatomic , strong)NSMutableDictionary<NSNumber *, NSDate *> *weeks;
/**   */
@property (nonatomic , assign)BOOL needsRequestingBoundingDates;

@end

@implementation LGWeekdayCalendar

- (instancetype)initWithFrame:(CGRect)frame{
    self = [super initWithFrame:frame];
    if (self) {
        self.needsRequestingBoundingDates = YES;
        self.minimumDate = [self.formatter dateFromString:@"1970-01-01"];
        self.maximumDate = [self.formatter dateFromString:@"2022-10-20"];
        self.currentDate = [self.calendar fs_firstDayOfMonth:[NSDate date]];
        [self addSubview:self.collectionView];
//        [self performSelector:@selector(scrollToToday) withObject:nil afterDelay:1];
    }
    return self;
}

-(void)scrollToToday{
    [self scrollToDate:[NSDate date] animated:YES];
}

-(void)layoutSubviews{
    [super layoutSubviews];
    self.collectionView.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
}

- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView{
    [self requestBoundingDatesIfNecessary];
    //开始日期所在周的第一天
    NSDate *fromDate = [self.calendar fs_firstDayOfWeek:self.minimumDate];
    NSInteger count = [self.calendar components:NSCalendarUnitWeekOfYear fromDate:fromDate toDate:self.maximumDate options:0].weekOfYear+1;
    return count;
}

- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section{
    return 7;
}

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath{
    NSDate *currentPage = [self weekForSection:indexPath.section];
    NSDate *date = [self.calendar dateByAddingUnit:NSCalendarUnitDay value:indexPath.item toDate:currentPage options:0];
    LGWeekdayCalendarCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:FSCalendarDefaultCellReuseIdentifier forIndexPath:indexPath];
    cell.isSelected = [[self.formatter stringFromDate:date] isEqualToString:[self.formatter stringFromDate:self.currentDate]];
    cell.date = date;
    return cell;
}

- (NSDate *)weekForSection:(NSInteger)section{
    NSNumber *key = @(section);
    NSDate *week = self.weeks[key];
    if (!week) {
        week = [self.calendar dateByAddingUnit:NSCalendarUnitWeekOfYear value:section toDate:[self.calendar fs_firstDayOfWeek:self.minimumDate] options:0];
        self.weeks[key] = week;
    }
    return week;
}



#pragma mark - <UICollectionViewDelegate>
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath{
    LGWeekdayCalendarCell *cell = (LGWeekdayCalendarCell *)[collectionView cellForItemAtIndexPath:indexPath];
    self.currentDate = cell.date;
    [self.collectionView reloadData];
}

- (void)scrollToDate:(NSDate *)date animated:(BOOL)animated{
    if (!_minimumDate || !_maximumDate) {
        return;
    }
//    animated &= _scrollEnabled; // No animation if _scrollEnabled == NO;
    
    date = [self safeDateForDate:date];
    NSIndexPath *toIndexPath = [self indexPathForDate:date];
    [_collectionView scrollToItemAtIndexPath:toIndexPath atScrollPosition:UICollectionViewScrollPositionCenteredHorizontally animated:YES];
}

- (NSDate *)safeDateForDate:(NSDate *)date{
    if ([self.calendar compareDate:date toDate:self.minimumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedAscending) {
        date = self.minimumDate;
    } else if ([self.calendar compareDate:date toDate:self.maximumDate toUnitGranularity:NSCalendarUnitDay] == NSOrderedDescending) {
        date = self.maximumDate;
    }
    return date;
}

- (NSIndexPath *)indexPathForDate:(NSDate *)date {
    if (!date) return nil;
    NSInteger item = 0;
    NSInteger section = 0;
    section = [self.calendar components:NSCalendarUnitWeekOfYear fromDate:[self.calendar fs_firstDayOfWeek:self.minimumDate] toDate:[self.calendar fs_firstDayOfWeek:date] options:0].weekOfYear;
    item = (([self.calendar component:NSCalendarUnitWeekday fromDate:date] - self.calendar.firstWeekday) + 7) % 7;
    if (item < 0 || section < 0) {
        return nil;
    }
    NSIndexPath *indexPath = [NSIndexPath indexPathForItem:item inSection:section];
    return indexPath;
}

- (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoint)velocity targetContentOffset:(inout CGPoint *)targetContentOffset{

//    CGFloat targetOffset = 0, contentSize = 0;
//    targetOffset = targetContentOffset->x;
//    contentSize = scrollView.fs_width;
    
//    self.sections = lrint(targetOffset/contentSize);
    
    
    // Disable all inner gestures to avoid missing event
//    [scrollView.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//        if (obj != scrollView.panGestureRecognizer) {
//            obj.enabled = NO;
//        }
//    }];
}



- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView{
//    NSDate *targetPage = nil;
//    NSDate *minimumPage = [self.gregorian fs_middleDayOfWeek:_minimumDate];
//    targetPage = [self.gregorian dateByAddingUnit:NSCalendarUnitWeekOfYear value:self.sections toDate:minimumPage options:0];
//
//    BOOL shouldTriggerPageChange = [self isDateInDifferentPage:targetPage];
//    if (shouldTriggerPageChange) {
//        NSDate *lastPage = _;
//        [self willChangeValueForKey:@"currentPage"];
//        _currentPage = targetPage;
////        [self.delegateProxy calendarCurrentPageDidChange:self];
////        if (_placeholderType != FSCalendarPlaceholderTypeFillSixRows) {
////            [self.transitionCoordinator performBoundingRectTransitionFromMonth:lastPage toMonth:_currentPage duration:0.25];
////        }
//        [self didChangeValueForKey:@"currentPage"];
//    }
//    // Recover all disabled gestures
//    [scrollView.gestureRecognizers enumerateObjectsUsingBlock:^(__kindof UIGestureRecognizer * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
//        if (obj != scrollView.panGestureRecognizer) {
//            obj.enabled = YES;
//        }
//    }];
}

//- (BOOL)isDateInDifferentPage:(NSDate *)date{
//    return ![self.gregorian isDate:date equalToDate:_currentPage toUnitGranularity:NSCalendarUnitWeekOfYear];
//}
- (BOOL)requestBoundingDatesIfNecessary{
    if (_needsRequestingBoundingDates) {
        _needsRequestingBoundingDates = NO;
        NSDate *newMin = [self.formatter dateFromString:@"1970-01-01"];
//        newMin = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:newMin options:0];
        NSDate *newMax = [self.formatter dateFromString:@"2022-10-20"];
//        newMax = [self.gregorian dateBySettingHour:0 minute:0 second:0 ofDate:newMax options:0];
        
        NSAssert([self.calendar compareDate:newMin toDate:newMax toUnitGranularity:NSCalendarUnitDay] != NSOrderedDescending, @"The minimum date of calendar should be earlier than the maximum.");
        
        BOOL res = ![self.calendar isDate:newMin inSameDayAsDate:_minimumDate] || ![self.calendar isDate:newMax inSameDayAsDate:_maximumDate];
        _minimumDate = newMin;
        _maximumDate = newMax;
//        [self.calculator reloadSections];
        
        return res;
    }
    return NO;
}


//- (nullable LGWeekdayCalendarCell *)cellForDate:(NSDate *)date atMonthPosition:(LGCalendarMonthPosition)position{
//    NSIndexPath *indexPath = [self.calculator indexPathForDate:date atMonthPosition:position];
//    return (LGWeekdayCalendarCell *)[self.collectionView cellForItemAtIndexPath:indexPath];
//}

//- (NSDate *)dateForCell:(LGWeekdayCalendarCell *)cell{
//    NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
//    return [self.calculator dateForIndexPath:indexPath];
//}

//- (FSCalendarMonthPosition)monthPositionForCell:(LGWeekdayCalendarCell *)cell{
//    NSIndexPath *indexPath = [self.collectionView indexPathForCell:cell];
//    return [self.calculator monthPositionForIndexPath:indexPath];
//}

- (NSArray<LGWeekdayCalendarCell *> *)visibleCells{
    return [self.collectionView.visibleCells filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id  _Nullable evaluatedObject, NSDictionary<NSString *,id> * _Nullable bindings) {
        return [evaluatedObject isKindOfClass:[LGWeekdayCalendarCell class]];
    }]];
}


#pragma mark
#pragma mark ====> 懒加载
-(UICollectionView *)collectionView{
    if(!_collectionView){
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc]init];
        layout.scrollDirection = UICollectionViewScrollDirectionHorizontal;
        layout.itemSize = CGSizeMake((Screen_W)/7.0, viewPix(90));
        layout.minimumInteritemSpacing = 0;
        layout.minimumLineSpacing = 0;
        _collectionView = [[UICollectionView alloc]initWithFrame:CGRectZero collectionViewLayout:layout];
        _collectionView.dataSource = self;
        _collectionView.delegate = self;
        _collectionView.backgroundColor = [UIColor clearColor];
        _collectionView.pagingEnabled = YES;
        _collectionView.showsHorizontalScrollIndicator = NO;
        _collectionView.showsVerticalScrollIndicator = NO;
        _collectionView.allowsMultipleSelection = NO;
        _collectionView.clipsToBounds = YES;
        [_collectionView registerClass:[LGWeekdayCalendarCell class] forCellWithReuseIdentifier:FSCalendarDefaultCellReuseIdentifier];
    }
    return _collectionView;
}

-(NSCalendar *)calendar{
    if(!_calendar){
        _calendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSCalendarIdentifierGregorian];
        _calendar.timeZone = [NSTimeZone localTimeZone];
        _calendar.firstWeekday = 1;//设置每周的第1为星期几，默认指为1代表星期天
    }
    return _calendar;
}

-(NSDateFormatter *)formatter{
    if(!_formatter){
        _formatter = [[NSDateFormatter alloc]init];
        _formatter.dateFormat = @"yyyy-MM-dd";
    }
    return _formatter;
}

-(NSMutableDictionary *)weeks{
    if(!_weeks){
        _weeks = [NSMutableDictionary dictionary];
    }
    return _weeks;
}

@end
